home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk.zip / ERROR.C < prev    next >
C/C++ Source or Header  |  1991-04-09  |  8KB  |  346 lines

  1.  
  2. /********************************************
  3. error.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the Awk programming language as defined in
  8. Aho, Kernighan and Weinberger, The AWK Programming Language,
  9. Addison-Wesley, 1988.
  10.  
  11. See the accompaning file, LIMITATIONS, for restrictions
  12. regarding modification and redistribution of this
  13. program in source or binary form.
  14. ********************************************/
  15.  
  16.  
  17. /* $Log:    error.c,v $
  18.  * Revision 2.2  91/04/09  12:38:52  brennan
  19.  * added static to funct decls to satisfy STARDENT compiler
  20.  * 
  21.  * Revision 2.1  91/04/08  08:22:52  brennan
  22.  * VERSION 0.97
  23.  * 
  24. */
  25.  
  26.  
  27. #include  "mawk.h"
  28. #include  "scan.h"
  29. #include  "bi_vars.h"
  30.  
  31. #ifndef  EOF
  32. #define  EOF  (-1)
  33. #endif
  34.  
  35. /* statics */
  36. static void  PROTO( check_FILENAME, (void) ) ;
  37. static void  PROTO( unexpected_char, (void) ) ;
  38. static void  PROTO( missing, (int, char *, int) ) ;
  39. static char *PROTO( type_to_str, (int) ) ;
  40.  
  41.  
  42. static struct token_str  {
  43. short token ;
  44. char *str ; }  token_str[] = {
  45. EOF , "end of file" ,
  46. NL , "end of line",
  47. SEMI_COLON , ";" ,
  48. LBRACE , "{" ,
  49. RBRACE , "}" ,
  50. SC_FAKE_SEMI_COLON, "}",
  51. LPAREN , "(" ,
  52. RPAREN , ")" ,
  53. LBOX , "[",
  54. RBOX , "]",
  55. QMARK , "?",
  56. COLON , ":",
  57. OR, "||",
  58. AND, "&&",
  59. P_OR, "||",
  60. P_AND, "&&",
  61. ASSIGN , "=" ,
  62. ADD_ASG, "+=",
  63. SUB_ASG, "-=",
  64. MUL_ASG, "*=",
  65. DIV_ASG, "/=",
  66. MOD_ASG, "%=",
  67. POW_ASG, "^=",
  68. EQ  , "==" ,
  69. NEQ , "!=",
  70. LT, "<" ,
  71. LTE, "<=" ,
  72. GT, ">",
  73. GTE, ">=" ,
  74. MATCH, "~",
  75. NOT_MATCH, "!~",
  76. PLUS , "+" ,
  77. MINUS, "-" ,
  78. MUL , "*" ,
  79. DIV, "/"  , 
  80. MOD, "%" ,
  81. POW, "^" ,
  82. INC , "++" ,
  83. DEC , "--" ,
  84. NOT, "!" ,
  85. COMMA, "," ,
  86. CONSTANT , temp_buff.string_buff ,
  87. ID , temp_buff.string_buff ,
  88. FUNCT_ID , temp_buff.string_buff ,
  89. BUILTIN , temp_buff.string_buff ,
  90. IO_OUT, temp_buff.string_buff, 
  91. IO_IN, "<" ,
  92. PIPE, "|" ,
  93. DOLLAR, "$" ,
  94. FIELD, "$" ,
  95. 0, (char *) 0 } ;
  96.  
  97. /* if paren_cnt >0 and we see one of these, we are missing a ')' */
  98. static int missing_rparen[] =
  99. { EOF, NL, SEMI_COLON, SC_FAKE_SEMI_COLON, RBRACE, 0 } ;
  100.  
  101. /* ditto for '}' */
  102. static int missing_rbrace[] =
  103. { EOF, BEGIN, END , 0 } ;
  104.  
  105. static void missing( c, n , ln)
  106.   int c ;
  107.   char *n ;
  108.   int ln ;
  109. { errmsg(0, "line %u: missing %c near %s" , ln, c, n) ; }
  110.   
  111. void  yyerror(s)
  112.   char *s ; /* we won't use s as input 
  113.   (yacc and bison force this).
  114.   We will use s for storage to keep lint or the compiler
  115.   off our back */
  116. { struct token_str *p ;
  117.   int *ip ;
  118.  
  119.   s = (char *) 0 ;
  120.  
  121.   for ( p = token_str ; p->token ; p++ )
  122.       if ( current_token == p->token )
  123.       { s = p->str ; break ; }
  124.  
  125.   if ( ! s )  /* search the keywords */
  126.          s = find_kw_str(current_token) ;
  127.  
  128.   if ( s )
  129.   {
  130.     if ( paren_cnt )
  131.         for( ip = missing_rparen ; *ip ; ip++)
  132.           if ( *ip == current_token )
  133.           { missing(')', s, token_lineno) ;
  134.             paren_cnt = 0 ;
  135.             goto done ;
  136.           }
  137.  
  138.     if ( brace_cnt )
  139.         for( ip = missing_rbrace ; *ip ; ip++)
  140.           if ( *ip == current_token )
  141.           { missing('}', s, token_lineno) ;
  142.             brace_cnt = 0 ;
  143.             goto done ;
  144.           }
  145.  
  146.     compile_error("syntax error at or near %s", s) ;
  147.  
  148.   }
  149.   else  /* special cases */
  150.   switch ( current_token )
  151.   {
  152.     case UNEXPECTED :
  153.             unexpected_char() ; 
  154.             goto done ;
  155.  
  156.     case BAD_DECIMAL :
  157.             compile_error(
  158.               "syntax error in decimal constant %s",
  159.               temp_buff.string_buff ) ;
  160.             break ;
  161.  
  162.     case RE :
  163.             compile_error(
  164.             "syntax error at or near /%s/", 
  165.             temp_buff.string_buff ) ;
  166.             break ;
  167.  
  168.     default :
  169.             compile_error("syntax error") ;
  170.             break ;
  171.   }
  172.   return ;
  173.  
  174. done :
  175.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  176. }
  177.  
  178. /* system provided errnos and messages */
  179. extern int sys_nerr ;
  180. extern char *sys_errlist[] ;
  181.  
  182. #ifdef  __STDC__
  183. #include <stdarg.h>
  184.  
  185. /* generic error message with a hook into the system error 
  186.    messages if errnum > 0 */
  187.  
  188. void  errmsg(int errnum, char *format, ...)
  189. { va_list args ;
  190.  
  191.   fprintf(stderr, "%s: " , progname) ;
  192.   va_start(args, format) ;
  193.   (void) vfprintf(stderr, format, args) ;
  194.   va_end(args) ;
  195.   if ( errnum > 0 && errnum < sys_nerr )
  196.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  197.   fprintf( stderr, "\n") ;
  198. }
  199.  
  200. void  compile_error(char *format, ...)
  201. { va_list args ;
  202.  
  203.   fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
  204.   va_start(args, format) ;
  205.   vfprintf(stderr, format, args) ;
  206.   va_end(args) ;
  207.   fprintf(stderr, "\n") ;
  208.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  209. }
  210.  
  211. void  rt_error( char *format, ...)
  212. { va_list args ;
  213.  
  214.   fprintf(stderr, "%s: run time error: " , progname ) ;
  215.   va_start(args, format) ;
  216.   vfprintf(stderr, format, args) ;
  217.   va_end(args) ;
  218.   check_FILENAME() ;
  219.   fprintf(stderr, "\n\t(FILENAME=\"%s\" FNR=%g NR=%g)\n" ,
  220.      string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
  221.      bi_vars[NR].dval) ;
  222.   mawk_exit(1) ;
  223. }
  224.  
  225. #else
  226.  
  227. #include <varargs.h>
  228.  
  229. /*  void errmsg(errnum, format, ...) */
  230.  
  231. void  errmsg( va_alist)
  232.   va_dcl
  233. { va_list ap ;
  234.   int errnum ;
  235.   char *format ;
  236.  
  237.   fprintf(stderr, "%s: " , progname) ;
  238.   va_start(ap) ;
  239.   errnum = va_arg(ap, int) ;
  240.   format = va_arg(ap, char *) ;
  241.   (void) vfprintf(stderr, format, ap) ;
  242.   if ( errnum > 0 && errnum < sys_nerr )
  243.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  244.   fprintf( stderr, "\n") ;
  245. }
  246.  
  247. void compile_error( va_alist )
  248.   va_dcl
  249. { va_list args ;
  250.   char *format ;
  251.  
  252.   fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
  253.   va_start(args) ;
  254.   format = va_arg(args, char *) ;
  255.   vfprintf(stderr, format, args) ;
  256.   va_end(args) ;
  257.   fprintf(stderr, "\n") ;
  258.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  259. }
  260.  
  261. void  rt_error( va_alist )
  262.   va_dcl
  263. { va_list args ;
  264.   char *format ;
  265.  
  266.   fprintf(stderr, "%s: run time error: " , progname ) ;
  267.   va_start(args) ;
  268.   format = va_arg(args, char *) ;
  269.   vfprintf(stderr, format, args) ;
  270.   va_end(args) ;
  271.   check_FILENAME() ;
  272.   fprintf(stderr, "\n\tFILENAME=\"%s\" FNR=%g NR=%g\n" ,
  273.      string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
  274.      bi_vars[NR].dval) ;
  275.   mawk_exit(1) ;
  276. }
  277.  
  278. #endif
  279.  
  280. void bozo(s)
  281.   char *s ;
  282. { errmsg(0, "bozo: %s" , s) ; mawk_exit(1) ; }
  283.  
  284. void overflow(s, size)
  285.   char *s ; unsigned size ;
  286. { errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
  287.   mawk_exit(1) ; }
  288.  
  289. static void check_FILENAME()
  290. {
  291.   if ( bi_vars[FILENAME].type != C_STRING )
  292.           cast1_to_s(bi_vars + FILENAME) ;
  293.   if ( bi_vars[FNR].type != C_DOUBLE )
  294.           cast1_to_d(bi_vars + FNR ) ;
  295.   if ( bi_vars[NR].type != C_DOUBLE )
  296.           cast1_to_d(bi_vars + NR ) ;
  297. }
  298.  
  299. /* run time */
  300. void rt_overflow(s, size)
  301.   char *s ; unsigned size ;
  302. { check_FILENAME() ;
  303.   errmsg(0 , 
  304.   "program limit exceeded: %s size=%u\n\
  305. \t(FILENAME=\"%s\" FNR=%g NR=%g)", 
  306.    s, size, string(bi_vars+FILENAME)->str, 
  307.    bi_vars[FNR].dval,
  308.    bi_vars[NR].dval) ;
  309.    mawk_exit(1) ;
  310. }
  311.  
  312. static void unexpected_char()
  313. { int c = yylval.ival ;
  314.  
  315.   fprintf(stderr, "%s: %u: ", progname, token_lineno) ;
  316.   if ( c > ' ')
  317.       fprintf(stderr, "unexpected character '%c'\n" , c) ;
  318.   else
  319.       fprintf(stderr, "unexpected character 0x%02x\n" , c) ;
  320. }
  321.  
  322. static char *type_to_str( type )
  323.   int type ;
  324. { char *retval ;
  325.  
  326.   switch( type )
  327.   {
  328.     case  ST_VAR :  retval = "variable" ; break ;
  329.     case  ST_ARRAY :  retval = "array" ; break ;
  330.     case  ST_FUNCT :  retval = "function" ; break ;
  331.     case  ST_LOCAL_VAR : retval = "local variable" ; break ;
  332.     case  ST_LOCAL_ARRAY : retval = "local array" ; break ;
  333.     default : bozo("type_to_str") ;
  334.   }
  335.   return retval ;
  336. }
  337.  
  338. /* emit an error message about a type clash */
  339. void type_error(p)
  340.   SYMTAB *p ;
  341. { compile_error("illegal reference to %s %s", 
  342.     type_to_str(p->type) , p->name) ;
  343. }
  344.  
  345.  
  346.